class Local {
    constructor() {
        this.initLo();
    }
    setData(key, value) { // 保存键值对到本地
        if (typeof value === 'string') {
            return localStorage.setItem(key, value);
        }
        try {
            localStorage.setItem(key, JSON.stringify(value));
        } catch (err) {
            return err;
        }
    }
    getData(key) { // 获取指定key的数据
        const value = localStorage.getItem(key);
        try {
            return JSON.parse(value);
        } catch (err) {
            return value;
        }
    }
    removeData(key) { // 删除指定key的数据
        return localStorage.removeItem(key);
    }
    clearData() { // 删除所有的本地数据
        return localStorage.clear();
    }
    initLo() { // 初始化
        if (!window.localStorage) {
            throw new Error("浏览器不支持 localstorage 本地存储！！！")
        }
    }
}
(function local(local = '_local') {
    var _local = local;
    if (window[local]) return alert('属性名重复！！'), console.log('属性名重复！！');
    try {
        window[_local] = new Local();
        console.log('封装本地存储成功，可以直接使用 ' + _local + ' 对象来操作本地存储数据！')
    } catch (err) {
        console.log(err)
        return err;
    }
})()

Bmob.initialize("b25e6d18ad16a138", "wwj_SQ");
// Bmob.debug(true)

// popup页面的popup对象
var popup = null;
var username = '';
var target = [];
var objectId = '';

var actions = {
    getPopup() { // 得到popup页面的popup对象
        var views = chrome.extension.getViews({
            type: 'popup'
        });
        if (views.length > 0) {
            popup = views[0].popup;
            return views.popup;
        }
    },
    init() {
        if (_local.getData("bmob")) {
            var res = _local.getData("bmob");
            username = res.username;
            target = res.target;
            objectId = res.objectId;
            return true;
        } else {
            return false;
        }
    },
    async login(data) { // 登录；
        !data || (data.field = {}, data.field.userName = 'wuweijun', data.field.userPassword = 'wuweijun');
        Bmob.User.login(data.field.userName, data.field.userPassword).then(res => {
            if (res.sessionToken) {
                sendMessage("openMsg", '登录成功');
                username = res.username;
                target = res.target;
                objectId = res.objectId;

                if (target.length == 0) actions.setBookmarksData();
                actions.coverLocat2()
                setInterval(() => {
                    actions.coverLocat2();
                }, 1000 * 60 * 30);
            }
        }).catch(err => {
            sendMessage("openMsg", '登录失败');
        });
    },
    async register(data) { // 注册；
        return await Bmob.User.register(data.field);
    },
    updateStorage(objectId, callback) { // 更新用户缓存
        Bmob.User.updateStorage(objectId).then(res => {
            console.log(res);
            !callback || callback(res)
        }).catch(err => {
            console.log(err)
        });
    },
    // 上传书签数据
    setBookmarksData(callback) {
        actions.init()
        actions.getAllBookmarks(function (data) {
            var arr = actions.handleData(data);
            var step = 30;
            var _target = 100;
            if (!target || target.length == 0) {
                _target = 1;
                target = [1]
            } else {
                _target = Number(target[target.length - 1]) + 1;
                target.push(_target)
                if (target.length > 110) target = target.slice(-100);
            }

            const query = Bmob.Query('_User');
            query.set('id', objectId)
            query.set("target", target)
            query.save().then(res => {
                console.log(res)
                for (let index = 0; index < arr.length; index += step) {
                    const element = arr[index];

                    var tep = [];
                    if (index + step > arr.length) {
                        tep = arr.slice(index, arr.length)
                    } else {
                        tep = arr.slice(index, index + step)
                    }

                    upload(tep, _target);
                }
                if (arr.length == 0) {
                    const query = Bmob.Query('_User');
                    query.set('id', objectId)
                    target.pop()
                    query.set("target", target)
                    query.save().then(res => {
                        console.log(res)
                        actions.updateStorage(objectId);
                    }).catch(err => {})
                }
                setTimeout(() => {
                    actions.updateStorage(objectId);
                }, 1000);
                !callback || callback(res);
            }).catch(err => {
                !callback || callback(err);
                console.log(err)
            })

            // 上传部分数据
            function upload(data, target) {
                const query = Bmob.Query('bookmark');
                query.set('res', data);
                query.set("username", _local.getData("bmob").username)
                query.set('target', target);
                query.save().then(res => {
                    // console.log(res)
                }).catch(err => {
                    console.log(err)
                })
            }
        })
    },
    setData(data) { // 保存书签数据--网络数据
        return _local.setData("BookmarksData", data)
    },
    getData() { // 得到书签数据--网络数据
        return _local.getData("BookmarksData")
    },
    // 获取到服务器上的书签 
    getBookmarksCloud(target_, callback, _default) {
        if (!actions.init()) return;
        if (target.length == 0) { // 如果服务器上没有数据，则上传书签数据后再执行方法；
            actions.setBookmarksData()
            setTimeout(() => {
                actions.getBookmarksCloud(target_, callback, _default)
            }, 10000);
            return;
        }

        var query = Bmob.Query("bookmark");
        query.equalTo("username", "==", username);

        if (_default) { // 默认获取最新的数据
            query.equalTo("target", "==", Number(target[target.length - 1]));
        }
        if (target_) { // 获取指定的数据
            query.equalTo("target", "==", target_);
        }

        query.find().then(res => {
            console.log(res)
            tep(res)
        });

        function tep(res) {
            var data = [];
            for (let index = 0; index < res.length; index++) {
                const element = res[index];
                data = data.concat(element.res)
            };
            !callback || callback(data);
        }
    },
    // 使用网上的书签覆盖浏览器现有的书签：策略：先删除现有的所有书签，再创建
    coverLocat2() {
        actions.removeListener();
        actions.getAllBookmarks(function (res) { // 删除浏览器中的所有书签
            res.forEach(function (item, index) {
                chrome.bookmarks.removeTree(item.id, function (res) {
                    console.log(res)
                })
                if (index == res.length - 1) { // 判断全部删除完毕
                    setTimeout(() => {
                        callback()
                    }, 200);
                }
            })
            if (res.length == 0) {
                // actions.setBookmarksData(function () {
                //     actions.event_();
                // })
                callback()
            }
        })

        // 创建所有书签
        function callback() {
            actions.getBookmarksCloud(null, function (data) {
                data = actions.handleData(actions.handleDataReversal(data))
                var index = 0;
                var key = {}; // 保存id，因为创建书签后会有新的id
                computed(index)

                function computed(index) {
                    if (index >= data.length) {
                        setTimeout(() => {
                            actions.setBookmarksData(function () {
                                actions.event_();
                            })
                        }, 1000);
                        return
                    };
                    var item = data[index]
                    key[item.id] = '';
                    var tep = item.id;
                    if (key.hasOwnProperty(item.parentId)) {
                        item.parentId = key[item.parentId]
                    } else {
                        item.parentId = '1' // 这是在谷歌中的。
                    }

                    delete item.id;
                    try {
                        // console.log(item, key)
                        chrome.bookmarks.create(item, function (res) {
                            // console.log(res)
                            key[tep] = res ? res.id : '1';
                            computed(++index)
                        })
                    } catch (e) {
                        console.log('错误：', e, item, key)
                        computed(++index)
                    }
                }
            }, true)
        }
    },
    // 使用网上的书签覆盖浏览器现有的书签
    coverLocat(callback) {
        var flat = false;
        actions.removeListener()
        actions.getBookmarksCloud(null, function (data) {
            delete_(data, function () {
                if (data.length == 0) actions.event_();
                data.forEach(function (item, index) {
                    chrome.bookmarks.get(item.id, function (res) {
                        // console.log(res)
                        if (!res) { // 新增书签
                            delete item.id;
                            chrome.bookmarks.create(item, function (res) {
                                console.log(res)
                            })
                            flat = true;

                            if (index == data.length - 1) {
                                action.setBookmarksData()
                            }
                            return
                        }

                        res = res[0];
                        if (item.title != res.title || item.url != res.url) {
                            delete item.id;
                            delete item.parentId;
                            delete item.index;
                            chrome.bookmarks.update(item.id, item, function (res) {
                                console.log(res)
                            })
                        }
                        if (item.index != res.index || item.parentId != res.parentId) {
                            var id = item.id
                            delete item.id;
                            delete item.title;
                            delete item.url;
                            chrome.bookmarks.move(id, item, function (res) {
                                console.log(res)
                            })
                        }

                        // if (index == data.length - 1 && flat) {
                        // }
                        if (index == data.length - 1) {
                            actions.setBookmarksData(function () {
                                actions.event_();
                            })
                        }
                    })
                })
            })
        }, true)

        // 验证本地书签是否存在云端，不存在则删除本地书签
        function delete_(data, callback) {
            var dataArr = []
            data.forEach(function (item) {
                dataArr.push(item.id)
            })
            actions.getAllBookmarks(function (res) {
                var arr = actions.handleData(res);
                console.log(arr);
                arr.forEach(function (item) {
                    if (!dataArr.includes(item.id) && item.url) {
                        flat = true;
                        chrome.bookmarks.remove(item.id, function (res) {
                            console.log(res)
                        })
                    } else if (!dataArr.includes(item.id) && !item.url) {
                        flat = true;
                        chrome.bookmarks.removeTree(item.id, function (res) {
                            console.log(res)
                        })
                    }
                });
                !callback || callback(data)
            })
        }
    },
    // 书签变动是触发的事件
    event_() {
        actions.removeListener()
        setTimeout(() => {
            chrome.bookmarks.onCreated.addListener(myListener)
            chrome.bookmarks.onRemoved.addListener(myListener)
            chrome.bookmarks.onChanged.addListener(myListener)
            chrome.bookmarks.onMoved.addListener(myListener)
        }, 1000);
    },
    removeListener() {
        chrome.bookmarks.onCreated.removeListener(myListener)
        chrome.bookmarks.onRemoved.removeListener(myListener)
        chrome.bookmarks.onChanged.removeListener(myListener)
        chrome.bookmarks.onMoved.removeListener(myListener)
    },
    // 获取到浏览器的全部书签 
    getAllBookmarks(callback) {
        chrome.bookmarks.getTree(function (res) {
            // 谷歌浏览器
            if (res[0].children[0].title == "书签栏") {
                var data = res[0].children[0].children;
                // console.log(data);
                !callback || callback(data)
            }
        })
    },
    // 处理数据，将浏览器书签转换成array对象；
    handleData(data) {
        data.sort(function (a, b) {
            return a.index - b.index;
        })
        var arr = [];
        for (let index = 0; index < data.length; index++) {
            const element = data[index];
            var obj = {};
            obj.id = element.id;
            obj.title = element.title;
            obj.index = element.index;
            obj.parentId = element.parentId;
            if (element.url) {
                obj.url = element.url;
            }
            arr.push(obj);
            if (!element.url && element.children) {
                var childrenArr = actions.handleData(element.children)
                arr = arr.concat(childrenArr)
            }
        }
        return arr;
    },
    // 处理数据，将array对象转换成浏览器书签；
    handleDataReversal(data) {
        data.forEach(function (item, index) {
            if (item.url) {
                data.forEach(function (_item, _index) {
                    if (item.parentId == _item.id) {
                        if (_item.children) {
                            _item.children.push(item);
                        } else {
                            _item.children = [];
                            _item.children.push(item);
                        }
                        item.isdelete = true;
                    }
                })
            }
        })
        var arrData = [];
        data.forEach(function (item) {
            if (!item.isdelete) {
                arrData.push(Object.assign({}, item));
            } else {
                delete item.isdelete;
            }
        })
        data = null;
        console.log(arrData)

        // sort_(arrData)

        // function sort_(data) {
        //     data.forEach(function (item) {
        //         if (Array.isArray(item.children))
        //             sort_(item.children)
        //     })
        //     sort(data)
        // }

        // function sort(data) {
        //     data.sort(function (a, b) {
        //         return a.index - b.index;
        //     })
        // }
        return arrData;
    }
}


var isChage = false;
var suo = false;
var myListener = function () {
    if (suo) return;
    if (isChage) {
        suo = true;
        setTimeout(() => {
            suo = false;
            actions.setBookmarksData();
        }, 5000);
    }
    if (!isChage) {
        isChage = true;
        setTimeout(() => {
            isChage = false;
            actions.setBookmarksData();
        }, 5000);
    }
}
chrome.bookmarks.onImportBegan.addListener(function () {
    actions.removeListener()
})
chrome.bookmarks.onImportEnded.addListener(function () {
    actions.setBookmarksData(function () {
        actions.event_()
    });
})

if (_local.getData("bmob")) {
    var user = _local.getData("bmob")
    var data = {}
    data.field = {}, data.field.userName = user.username, data.field.userPassword = user.userPassword
    actions.login(actions)
} else {

}


/**
 * 发送信息
 * @fnName {String} 要执行的方法名称
 * @parameter {String,Array, Object...} 传递给执行的方法的参数
 **/
function sendMessage(openFn, parameter) {
    chrome.runtime.sendMessage({
        openFn: openFn,
        parameter: parameter
    }, function (response) {
        console.log('收到来自popup页面的回复：' + response);
        if (!response) return;
        var openFn = response.openFn;
        var parameter = response.parameter;
        if (actions[openFn]) {
            actions[openFn](parameter, sendResponse)
            // popup.openMsg.apply(this, parameter)
        }
    });
}